home *** CD-ROM | disk | FTP | other *** search
- ;WINHULLO.ASM --> WINHULLO.EXE Windows demo program.
-
- ;****NOTE**** these WINHULLO files may not be exactly the same as
- ;those listed in the textbook. The book listings were developed for
- ;Microsoft C version 6.00 and the SDK. The files have since been
- ;modified to work with Borland C++ version 2.0. Look at the code
- ;below and you will see where I have commented-out some code and
- ;replaced it with more efficient code that TASM can understand.
- ;You can convert back if necessary.
-
- .MODEL SMALL ;, WINDOWS PASCAL
-
- ;the following equates could have been placed in a separate
- ;include file.... (note that I got these from WINDOWS.H which is
- ;part of the Microsoft SDK)
- IDI_APPLICATION EQU 32512 ;identifier for icon type.
- IDC_ARROW EQU 32512 ;identifier for cursor type.
- OEM_FIXED_FONT EQU 10 ;identifier for font type.
- COLOR_BACKGROUND EQU 1 ;identifier for background colour.
-
- WM_CREATE EQU 1 ;these are messages from Windows.
- WM_DESTROY EQU 2 ; /
- WM_PAINT EQU 15 ; /
- WM_COMMAND EQU 273 ; /
- WM_LBUTTONDOWN EQU 513 ; /
- WM_CHAR EQU 258 ; /
-
- IDM_QUIT EQU 100 ;menu-identifiers from Windows -- must
- IDM_ABOUT EQU 101 ;be same as defined in .RC file.
-
- MB_OK EQU 0 ;a messagebox type.
-
- ;......
-
- EXTRN __acrtused:ABS
- EXTRN UPDATEWINDOW:FAR ;these are Windows functions.
- EXTRN BEGINPAINT:FAR
- EXTRN ENDPAINT:FAR
- EXTRN DEFWINDOWPROC:FAR
- EXTRN POSTQUITMESSAGE:FAR
- EXTRN REGISTERCLASS:FAR
- EXTRN GETSTOCKOBJECT:FAR
- EXTRN CREATEWINDOW:FAR
- EXTRN SHOWWINDOW:FAR
- EXTRN GETMESSAGE:FAR
- EXTRN LOADCURSOR:FAR
- EXTRN TRANSLATEMESSAGE:FAR
- EXTRN DISPATCHMESSAGE:FAR
- EXTRN LOADICON:FAR
- EXTRN TEXTOUT:FAR
- EXTRN INVALIDATERECT:FAR
- EXTRN MESSAGEBOX:FAR
- EXTRN GETDC:FAR
- EXTRN RELEASEDC:FAR
- EXTRN SELECTOBJECT:FAR
-
- .DATA
- wintitle DB 'HULLO DEMO PROGRAM',0
- winhulloname DB 'WINHULLO',0
- hOemFont DW 0 ;handle to OEM font.
- _hInst DW 0
- outstring DB 'Hullo World'
- aboutstr DB 'Assembly Language Windows Demo',0 ;messagebox
- titlestr DB 'Karda Prints',0 ; /
-
- .CODE
-
- ; PUBLIC WinMain
- ;WinMain PROC WINDOWS PASCAL NEAR nCmdShow:WORD,lpCmdLine:DWORD,hPrevInstance:WORD,hInstance:WORD
- ;****NOTE**** the above two lines are an enhancement available with TASM,
- ;providing high-level stack handling at procedure entry and exit... leave the lines
- ;commented-out, as this feature is not implemented fully in this file.
-
- PUBLIC WINMAIN
- WINMAIN PROC NEAR ;entry point from Windows.
- ; ;stack will contain return-addr (only 2
- ; ;bytes), nCmdShow (2), lpCmdLine (4),
- ; ;hPrevInstance (2), hInstance (2 bytes).
- ; ;(ret-addr is at top of stack).
- push bp ;save BP so can use to access params.
- mov bp,sp ;BP will now point to top-of-stack.
- sub sp,46 ;mov stack to free region.
- cmp WORD PTR [bp+10],0 ;hPrevInstance. (=0 if no previous inst).
- jne createwin
-
-
-
- ;we only come this way if this is the first instance of the application.
- ;The first instance needs to create certain resources, and all following
- ;instances can use them....
- ;(for this Workshop, skip ahead to "createwin:")
- ;The code below is creating a window-class data-structure, as required
- ;by RegisterClass() further down....
- mov WORD PTR [bp-46],3 ;wndclass
- mov WORD PTR [bp-44],OFFSET WinHulloProc ;addr of callback
- mov WORD PTR [bp-42],SEG WinHulloProc ;function for window.
- sub ax,ax
- mov WORD PTR [bp-40],ax
- mov WORD PTR [bp-38],ax
- mov ax,WORD PTR [bp+12] ;hInstance
- mov WORD PTR [bp-36],ax
- sub ax,ax ;null -- use Windows default icons.
- push ax ; /
- mov cx,IDI_APPLICATION ;Default application icon.
- sub dx,dx ; /
- push dx ; /
- push cx ; /
- call FAR PTR LOADICON
- mov WORD PTR [bp-34],ax
- sub ax,ax ;null -- use Windows default cursor.
- push ax ; /
- mov ax,IDC_ARROW ;Standard arrow cursor.
- cwd ; /
- push dx ; /
- push ax ; /
- call FAR PTR LOADCURSOR
- mov WORD PTR [bp-32],ax
- ; mov ax,WHITE_BRUSH
- ; push ax
- ; call FAR PTR GETSTOCKOBJECT
- mov ax,COLOR_BACKGROUND
- mov WORD PTR [bp-30],ax
- mov ax,OFFSET DGROUP:winhulloname
- mov WORD PTR [bp-28],ax
- mov WORD PTR [bp-26],ds
- mov WORD PTR [bp-24],ax
- mov WORD PTR [bp-22],ds
- lea ax,WORD PTR [bp-46] ;wndclass
- push ss ;this is address of above data
- push ax ;structure.
- call FAR PTR REGISTERCLASS ;registers this class of window.
- or ax,ax ;
- je quitwinmain
-
- createwin:
- ;CreateWindow() requires the following params on the stack --
- ;long pointer to window class name, lp to window title, type of window,
- ;x coord, y coord, width, height, parent-handle, menu-handle, instance-
- ;handle, lp to params to pass-on.
- mov ax,OFFSET DGROUP:winhulloname ;see _DATA segment.
- push ds ;long-pointer (far address) of
- push ax ;class-name.
- mov ax,OFFSET DGROUP:wintitle ;see _DATA segment.
- push ds ;far address of window-title.
- push ax ; /
- sub ax,ax ;type of window (32-bit value).
- mov dx,207 ; /
- push dx ; /
- push ax ; /
- mov ax,150 ;x-coord (16-bit).
- push ax ; /
- sub ax,ax ;y-coord (16-bit).
- push ax ; /
- mov ax,400 ;width (16-bit).
- push ax ; /
- mov ax,300 ;height (16-bit).
- push ax ; /
- sub ax,ax
- push ax ;0=no parent for this window.
- push ax ;0=use the class menu.
- mov ax,WORD PTR [bp+12] ;hInstance -- handle for this
- mov WORD PTR _hInst,ax ;application's instance.
- push ax ;(passed to applic from Windows).
- sub ax,ax
- push ax ;0=no params to pass-on.
- push ax ;(32-bit long-pointer).
- call FAR PTR CREATEWINDOW
- mov WORD PTR [bp-2],ax ;returns hWnd in AX
- ;(handle to the window).
- ;Here we save it temporarily.
-
- push ax ;ShowWindow() requires hWnd and
- push WORD PTR [bp+4] ;nCmdShow ;nCmdShow on the stack.
- call FAR PTR SHOWWINDOW ;Tells Windows to display window.
-
- push WORD PTR [bp-2] ;hWnd
- call FAR PTR UPDATEWINDOW ;tells Windows to redraw now.
- jmp SHORT messageloop ;go to the main message-loop.
-
-
- ;This is the main message loop, in which Windows waits for messages
- ;by calling GetMessage(), then translates keypresses with
- ;TranslateMessage() then passes them back to Windows with
- ;DispatchMessage()....
- mainloop:
- lea ax,WORD PTR [bp-20] ;far-addr of message.
- push ss ; /
- push ax ; /
- call FAR PTR TRANSLATEMESSAGE
-
- lea ax,WORD PTR [bp-20] ;far-addr of message.
- push ss ; /
- push ax ; /
- call FAR PTR DISPATCHMESSAGE
-
- messageloop:
- lea ax,WORD PTR [bp-20] ;long-pointer (far addr) of
- push ss ;message. (we use the stack
- push ax ;region for convenience).
- sub ax,ax
- push ax ;null
- push ax ;null
- push ax ;null
- call FAR PTR GETMESSAGE
- or ax,ax
- jne mainloop
-
- ;GetMessage() returns FALSE (AX=0) if a "quit" message...
- ;so here we are quiting....
- mov ax,WORD PTR [bp-16] ;return wParam to Windows.
- quitwinmain:
- mov sp,bp
- pop bp
- ret 10 ;Causes RET to add 10 to SP prior to
- ;popping ret-address, effectively dumping
- ;all params (as for PASCAL convention).
- WINMAIN ENDP
-
- ;.....................................................................
- ;What follows is the "callback" function, that Windows calls after the
- ;message has been given back to it via DispatchMessage().
- ;This function employs CASE logic to direct execution to specific
- ;routines to handle each message. In many cases the message
- ;cannot be handled by the application, so it is sent back to
- ;Windows (again!) for default handling....
-
- PUBLIC WinHulloProc
- WinHulloProc PROC FAR
- ;The function is entered with far-return-addr (4 bytes), lParam (4),
- ;wParam (2), message-type (2), and window-handle (2 bytes) on the stack
- ;(ret-addr on top).
-
- push ds ;This is some standard preliminary
- pop ax ;shuffling of the registers.
- nop ; /
- inc bp ; / (it is called the prolog code)
- push bp ; /
- mov bp,sp ; /
- push ds ; /
- mov ds,ax ; /
- ASSUME DS: NOTHING ; / (enters function with DS=_DATA)
-
- sub sp,146 ;move the stack to a free region
- ;(so as not to mess-up the params).
- mov ax,WORD PTR [bp+12] ;get message-type.
-
- cmp ax,WM_CREATE ;message received after CreateWindow()
- je xcreate ;function is called.
- cmp ax,WM_DESTROY ;message received if a window is closed.
- je xquitmessage
- cmp ax,WM_PAINT ;message received if Windows has (already)
- ;redrawn any part of the window (due to
- ;a size-change for example).
- je xpaint
- cmp ax,WM_COMMAND ;any selection of the menu will produce
- jne notwmcommand
- jmp xmenu ;this message.
- notwmcommand:
- cmp ax,WM_LBUTTONDOWN ;one of many mouse messages.
- jne notwmlbutton
- jmp xbreak
- notwmlbutton:
- cmp ax,WM_CHAR ;message that a key pressed.
- je xchar
-
- ;Default handling of messages....
- push WORD PTR [bp+14] ;hWnd
- push WORD PTR [bp+12] ;Message-type
- push WORD PTR [bp+10] ;wParam
- push WORD PTR [bp+8] ;hi-half of lParam
- push WORD PTR [bp+6] ;low-half of lParam
- call FAR PTR DEFWINDOWPROC
- jmp xreturn ;Back to Windows, which will in turn
- ;return to after DispatchMessage().
- ;.................................
- xcreate:
- mov ax,OEM_FIXED_FONT
- push ax
- call FAR PTR GETSTOCKOBJECT
- mov hOemFont,ax ;handle to font.
- jmp xbreak
-
- xquitmessage:
- sub ax,ax
- push ax
- call FAR PTR POSTQUITMESSAGE
- jmp xbreak
-
- xchar:
- ;If I wanted this program to display "Hullo World" only when any key is
- ;pressed, TextOut() would have been placed here.
- ;note below that BeginPaint() returned a "display context", a handle
- ;required for drawing, but we don't normally use BeginPaint() outside
- ;of WM_PAINT cases -- instead we use GetDC()....
- ;here is what the code would look like if placed here (in C)....
- ; hDC = GetDC(hWnd);
- ; TextOut(hDC,10,20,"Hullo World",11);
- ; ReleaseDC(hWnd,hDC);
- ;If we want the string to be redrawn everytime the window is redrawn,
- ;it is better to put TextOut() within the WM_PAINT case... this will
- ;also mean that "Hullo World" will appear when the window is first drawn.
- jmp xbreak
-
- xpaint:
- push WORD PTR [bp+14] ;hWnd -- handle of current window.
- lea ax,WORD PTR [bp-42] ;ps -- far-addr of paint-structure.
- push ss ;(BeginPaint() will fill the structure).
- push ax ; /
- call FAR PTR BEGINPAINT ;BeginPaint() returns handle hDC.
- mov WORD PTR [bp-146],ax ;hDC -- display-context, required
- ;before can output to screen.
-
- ;For this simple demo, any redraw of the Window will cause output of our
- ;"hullo world" string....
- ;Windows by default uses the System font, but I
- ;am changing it. I need to attach the new font to the
- ;display....
- ; push ax ;hDC
- ; push hOemFont
- ; call FAR PTR SELECTOBJECT ;attaches hOemFont to hDC.
-
- call SelectObject PASCAL,ax,hOemFont ;TASM replacement.
-
- push WORD PTR [bp-146] ;hDC ;hDC
- mov ax,10 ;16-bit x-coord
- push ax ; /
- mov ax,20 ;16-bit y-coord
- push ax ; /
- mov ax,offset outstring ;far-address of string to o/p
- push ds ; /
- push ax ; / (note low half pushed 2nd)
- mov ax,11 ;number of chars in string.
- push ax
- call FAR PTR TEXTOUT
-
- push WORD PTR [bp+14] ;hWnd
- lea ax,WORD PTR [bp-42] ;ps -- far-addr of paint-structure.
- push ss ;(filled by BeginPaint()).
- push ax ; /
- call FAR PTR ENDPAINT
- jmp SHORT xbreak
- ;........................
- xmenu:
- ;comes here if WM_COMMAND message. The two parameters associated with
- ;the message, lParam & wParam, tell us more....
- ;low-order word of lParam=0 if message is a menu-selection.
- ;hi-order word of lParam=1 if message is an accelerator-key.
- ;If low/lParam<>0, message is from a "control" (such as a scrollbar), and
- ;low/lParam=handle of control, hi/lParam=notification code.
- ;wParam contains the menu-item, the control-ID or the accelerator-key-ID.
-
- ;let's stick with menus... the .RC file assigns the number for each
- ;menu-item, and this is what we look for in wParam...
- cmp WORD PTR [bp+6],0 ;low-half of lParam
- jne xbreak ;test if a menu-message.
- cmp WORD PTR [bp+10],IDM_QUIT ;wParam.
- jne notquit
- jmp xquitmessage
- notquit:
- cmp WORD PTR [bp+10],IDM_ABOUT
- jne xbreak ;no other menu items.
- ;let's put up a message about this program...
- ; push WORD PTR [bp+14] ;hWnd -- handle of parent window.
- ; mov ax,OFFSET aboutstr ;far-addr of string to display.
- ; push ds ; /
- ; push ax ; /
- ; mov ax,OFFSET titlestr ;far-addr of title of dialog-box.
- ; push ds ; /
- ; push ax ; /
- ; mov ax,MB_OK ;type of message-box.
- ; push ax ; / (displays single "ok" button)
- ; call FAR PTR MESSAGEBOX
-
- call MessageBox PASCAL,WORD PTR [bp+14],SEG aboutstr,OFFSET aboutstr,SEG titlestr,OFFSET titlestr,MB_OK
- ;TASM replacement***
- ;.........................
- xbreak:
- sub ax,ax ;returns 0 in DX:AX. (callback functions
- cwd ;return a 32-bit (long) value).
- xreturn:
- dec bp ;final standard manipulation of regs.
- dec bp ; /
- mov sp,bp ; / (it is called the epilog code).
- pop ds ; /
- pop bp ; /
- dec bp ; /
- ret 10 ;removes parameters.
-
- WinHulloProc ENDP
-
- ;.....................................................................
-
- END
-